<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>防抖</title>
  <style>
    #container {
      width: 100%;
      height: 300px;
      text-align: center;
      line-height: 300px;
      background-color: #1b6d85;
    }
  </style>
</head>
<body>
<!--
  防抖的原理就是：你尽管触发事件，但是我一定在事件触发 n 秒后才执行,
  如果你在一个事件触发的 n 秒内又触发了这个事件，那我就以新的事件的时间为准，
  n 秒后才执行，总之，就是要等你触发完事件 n 秒内不再触发事件，我才执行，真是任性呐!
-->
<div id="container"></div>
</body>
<script>
  let container = document.getElementById('container')
  let count = 0
  function getCount(){
    count++
    //console.log(this) //值为 <div id="container">xx</div>  在防抖函数中指向window(定时器不用箭头函数的话)
    container.innerText = count.toString()
  }

  console.log(container.onmousemove)
  container.onmousemove = debounce(getCount, 20)
  console.log(container.onmousemove) //container.onmousemove 的值就是被返回来的函数.

  // 防抖 要防抖的方法 等待时间 是否立即执行一次 相当于vue中watch的immediate
  //function debounce(func, wait, immediate) {
  //  let timeout
  //  return function () {
  //    //将 this 指向正确的对象。
  //    const context = this
  //    //event 对象的指向  否则为undefined
  //    const args = arguments
  //
  //    //以新的事件的时间为准
  //    if (timeout) clearTimeout(timeout);
  //    if (immediate) {
  //      // 若没有定时器 callNow的值为真
  //      const callNow = !timeout
  //      timeout = setTimeout(function(){
  //        timeout = null;
  //      }, wait)
  //      // 立即执行一次
  //      if (callNow) func.apply(context, args)
  //    } else {
  //      timeout = setTimeout(function(){
  //        func.apply(context, args)
  //      }, wait);
  //    }
  //  }
  //}

  //手写
  function debounce(fun, wait) {
    let timer = null
    return function() {
      let that = this
      let args = arguments
      clearTimeout(timer)
      timer = setTimeout(() => {
        fun.apply(that, args)
      },wait)
    }
  }

</script>
</html>
